/*******************************************
 * Copyright 2007 Aphrodite Framework for javaME .
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Public License v2.0
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 * Email : owner@aphroditeme.dev.java.net
 * Contributors:
 *     Kent Elton - initial API and implementation
 *******************************************/

package com.aphrodite.ui.widgets;

import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;

import com.aphrodite.util.StringUtil;

/**
 * A speech bubble widget
 * <p>
 * Background,Title cannot be set for this widget.<br/> <img
 * src="../../../resources/aphro_speech.png">
 * </p>
 * 
 * 
 * @author kentelt
 * 
 */
public final class SpeechBubble extends Widget {

	public static final byte BOTTOM = 2;
	public static final byte LEFT = 3;

	private static final int PADDING = 6;

	public static final byte RIGHT = 4;
	public static final byte TOP = 1;

	private int arrowHeight = 7;
	private byte arrowLocation = BOTTOM;
	private int arrowWidth = 4;
	private int arrowX;
	private int arrowY;
	private Image bubbleImage;
	private String[] lines;
	private String message;

	/**
	 * 
	 * @param message
	 * @param bubbleIcon
	 *            if null no icon is used. icon width is always less than the
	 *            bubble width
	 * @param x
	 *            coordinate of the bubble arrow
	 * @param y
	 *            coordinate of the bubble arrow
	 * @param width
	 * @param location
	 *            location of the bubble arrow. Use the class constants
	 *            specified.
	 */
	public SpeechBubble(Theme theme, String message, Image bubbleIcon, int x, int y, int width, byte arrowLocation) {
		super(theme, width, 0);
		arrowX = x;
		arrowY = y;
		this.message = message;
		this.bubbleImage = bubbleIcon;
		this.arrowLocation = arrowLocation;
		updateModel();
	}

	public void cleanUp() {
		lines = null;

	}

	private void drawSpeechBubble(Graphics g) {
		// init(g, width, height + arrowHeight, false);
		g.translate(x, y);
		renderBubble(g);
		renderString(g);
		g.translate(-x, -y);

	}

	/**
	 * Draw an image inside a speech bubble
	 * 
	 * @param g
	 *            , the graphics object
	 * @param im
	 *            , the image we want to draw
	 * @param x
	 *            , the x position of the bubble relative to the arrow
	 * @param y
	 *            , the y position of the bubble relative to the arrow
	 */
	public void paintImage(Graphics g, Image im, int x, int y) {
		if (g == null || im == null)
			return;
		// drawBubble(g, x, y, im.getHeight() + PADDING, im.getWidth() +
		// PADDING);
		g.drawImage(im, x, y - arrowHeight - im.getHeight() / 2 - PADDING / 2, Graphics.HCENTER | Graphics.VCENTER);
	}

	public void render(final Graphics g) {
		if (!isVisible)
			return;
		drawSpeechBubble(g);

	}

	private final void renderBubble(final Graphics g) {
		switch (arrowLocation) {
		case BOTTOM:
			g.setColor(theme.bgColor);
			g.fillRoundRect(0, 0, width, height, PADDING * 2, PADDING * 2);
			g.setColor(theme.borderColor);
			g.drawRoundRect(0, 0, width, height, PADDING * 2, PADDING * 2);
			g.setColor(theme.bgColor);
			g.fillTriangle((width / 2) - (arrowWidth / 2), height, width / 2, height + arrowHeight, (width / 2)
					+ (arrowWidth / 2), height);
			// // This is the outline to the pointy part
			g.setColor(theme.borderColor);
			// \
			g.drawLine((width / 2) - (arrowWidth / 2), height, width / 2, height + arrowHeight);
			// /
			g.drawLine((width / 2) + (arrowWidth / 2), height, width / 2, height + arrowHeight);
			break;
		case TOP:
			g.setColor(theme.bgColor);
			g.fillRoundRect(0, arrowHeight, width, height, PADDING * 2, PADDING * 2);
			g.setColor(theme.borderColor);
			g.drawRoundRect(0, arrowHeight, width, height, PADDING * 2, PADDING * 2);
			g.setColor(theme.bgColor);
			g.fillTriangle((width / 2) + (arrowWidth / 2), arrowHeight + 1, width / 2, 0, (width / 2)
					- (arrowWidth / 2), arrowHeight + 1);
			g.setColor(theme.borderColor);
			g.drawLine((width / 2) - (arrowWidth / 2), arrowHeight, width / 2, 0);
			g.drawLine((width / 2) + (arrowWidth / 2), arrowHeight, width / 2, 0);
			break;
		case LEFT:
			g.setColor(theme.bgColor);
			g.fillRoundRect(0, 0, width, height, PADDING * 2, PADDING * 2);
			g.setColor(theme.borderColor);
			g.drawRoundRect(0, 0, width, height, PADDING * 2, PADDING * 2);
			g.setColor(theme.bgColor);
			g.fillTriangle(width, (height / 2) - (arrowWidth / 2), width + arrowHeight, height / 2, width, (height / 2)
					+ (arrowWidth / 2));
			g.setColor(theme.borderColor);
			g.drawLine(width, (height / 2) - (arrowWidth / 2), width + arrowHeight, height / 2);
			g.drawLine(width, (height / 2) + (arrowWidth / 2), width + arrowHeight, height / 2);
			break;
		case RIGHT:
			g.setColor(theme.bgColor);
			g.fillRoundRect(arrowHeight, 0, width, height, PADDING * 2, PADDING * 2);
			g.setColor(theme.borderColor);
			g.drawRoundRect(arrowHeight, 0, width, height, PADDING * 2, PADDING * 2);
			g.setColor(theme.bgColor);
			g.fillTriangle(arrowHeight + 1, (height / 2) - (arrowWidth / 2), 0, height / 2, arrowHeight + 1,
					(height / 2) + (arrowWidth / 2));
			g.setColor(theme.borderColor);
			g.drawLine(arrowHeight, (height / 2) - (arrowWidth / 2), 0, height / 2);
			g.drawLine(arrowHeight, (height / 2) + (arrowWidth / 2), 0, height / 2);
			break;
		}
	}

	private final void renderString(final Graphics g) {
		g.setColor(theme.fgColor);
		g.setFont(theme.widgetFont);
		int yPad = PADDING;
		int xPad = 2;
		switch (arrowLocation) {
		case BOTTOM:
			break;
		case TOP:
			yPad = arrowHeight + PADDING;
			break;
		case LEFT:
			yPad = PADDING;
			break;
		case RIGHT:
			yPad = PADDING;
			xPad = 2 + arrowHeight;
			break;
		}
		for (int i = 0; i < lines.length; i++) {
			g.drawString(lines[i], xPad, yPad + theme.widgetFont.getHeight() * i, 0);
		}
	}

	/**
	 * 
	 * @param height
	 *            less than SpeechBubble height
	 */
	public final void setArrowHeight(final int height) {
		if (height > this.height)
			return;
		this.arrowHeight = height;
	}

	/**
	 * 
	 * @param x
	 *            of the bubble arrow
	 * @param y
	 *            of the bubble arrow
	 */
	public final void setArrowLocation(final int x, final int y) {
		this.arrowX = x;
		this.arrowY = y;
		updateModel();
		reDrawWidget();
	}

	/**
	 * 
	 * @param width
	 *            less than SpeechBubble width
	 */
	public final void setArrowWidth(final int width) {
		if (width > this.width)
			return;
		this.arrowWidth = width;
	}

	// public final void setFont(final Font font) {
	// super.setFont(font);
	// updateModel();
	// }

	public final void setMessage(final String message) {
		this.message = message;
		updateModel();
		reDrawWidget();
	}

	public final void setTitle(String title) {

	}

	protected void updateModel() {
		int messageWidth = width - 4;
		lines = StringUtil.doTextWrap(message, theme.widgetFont, messageWidth, messageWidth);
		height = PADDING + theme.widgetFont.getHeight() * lines.length;
		switch (arrowLocation) {
		case BOTTOM:
			y = arrowY - (arrowHeight + height);
			x = arrowX - (width / 2);
			break;
		case TOP:
			x = arrowX - (width / 2);// arrowX;
			y = arrowY;
			break;
		case LEFT:
			x = arrowX - (arrowHeight + width);
			y = arrowY - (height / 2);
		case RIGHT:
			x = arrowX;
			y = arrowY - (height / 2);
			break;
		}

		System.out.println("x: " + x + " y: " + y);
		System.out.println("bubble height " + height);
	}

}
